/*
 * @Author: wuqingchun
 * @Date: 2024-06-24 10:04:02
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-06-24 13:46:26
 */

#include <cstring>
#include <thread>
#include <cassert>
#include <atomic>

class CAppSafeFence
{
public:
    CAppSafeFence()
    {
        m_objConsumer = std::thread(&CAppSafeFence::__Consumer, this);
        m_objProducer = std::thread(&CAppSafeFence::__Producer, this);
    }

    ~CAppSafeFence()
    {
        m_objConsumer.join();
        m_objProducer.join();
    }
private:

    enum class EOperStatus
    {
        OPER_INIT,
        OPER_SUCCESS,
        OPER_FAIL,
    };

    void __Producer()
    {
        EOperStatus enStatus = EOperStatus::OPER_FAIL;

        char* pcData = new (std::nothrow) char[256];
        if (pcData == nullptr)
        {
            m_pcData = nullptr;
            m_iData = 100;
            enStatus = EOperStatus::OPER_FAIL;
        }
        else
        {
            (void)strcpy(pcData, "Hello world!");
            m_pcData = pcData;
            m_iData = 200;
            enStatus = EOperStatus::OPER_SUCCESS;
        } 

        // 设置内存屏障（栅栏），
        std::atomic_thread_fence(std::memory_order_release);
        m_eOperStatus = enStatus;       
    }

    void __Consumer()
    {
        // m_eOperStatus 变量在函数内没有修改，编译器在生成代码时会进行内存访问优化
        // 将变量 m_eOperStatus 的值加载的寄存器中，后续变量的值直接从寄存器中获取，
        // 而不会访问变量的内存
        // 存在的问题 - 死循环，m_eOperStatus 可能会被其他的函数修改
        // 在定义 m_eOperStatus 时使用 volatile 关键字进行修饰，禁用编译器对变量进行访存优化
        while (m_eOperStatus == EOperStatus::OPER_INIT)
        {

        }

        std::atomic_thread_fence(std::memory_order_acquire);

        assert(m_iData != 0);
        assert(m_pcData != nullptr);
    }

private:

    // volatile 禁止编译器优化
    volatile EOperStatus m_eOperStatus{EOperStatus::OPER_INIT};

    char* m_pcData {nullptr};
    int32_t m_iData = 0;

    std::thread m_objProducer;
    std::thread m_objConsumer;
};


int main(int argc, char** argv)
{
    CAppSafeFence objApp;

    
    return 0;
}